home *** CD-ROM | disk | FTP | other *** search
- /* The values key_start & key_inc are searched by correlation on a few
- * lines & columns of the frame. Please read the licence in the README
- * file before using this code. */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <assert.h>
-
- #include "nagra.h"
-
- #define KEY_BUF_SIZE 25
- int key_locked;
- int key_buf_ptr=0;
- int key_buf[KEY_BUF_SIZE];
-
- char table_keys[256] = {
- 0,1,2,3,4,5,6,7,2,5,4,7,8,9,10,11,14,17,16,19,22,
- 25,24,27,28,31,30,1,24,27,26,29,8,11,10,13,20,23,
- 22,25,20,21,22,23,30,31,0,1,16,17,18,19,28,29,30,
- 31,10,11,12,13,16,17,18,19,12,15,14,17,0,1,2,3,20,
- 23,22,25,18,19,20,21,22,25,24,27,26,27,28,29,18,
- 21,20,23,10,13,12,15,28,29,30,31,4,5,6,7,22,23,24,
- 25,4,7,6,9,30,1,0,3,26,29,28,31,2,5,4,7,8,9,10,11,
- 14,15,16,17,24,27,26,29,14,17,16,19,6,9,8,11,16,
- 19,18,21,28,31,30,1,24,25,26,27,20,21,22,23,0,3,2,
- 5,6,7,8,9,12,13,14,15,8,11,10,13,2,3,4,5,30,31,0,
- 1,24,25,26,27,2,3,4,5,30,1,0,3,6,9,8,11,12,15,14,
- 17,26,27,28,29,14,15,16,17,18,19,20,21,22,23,24,
- 25,4,7,6,9,18,21,20,23,12,13,14,15,16,19,18,21,26,
- 29,28,31,10,11,12,13,10,13,12,15,6,7,8,9,0,3,2,5
- };
-
-
- /* #define PROFILE */
-
- /* define it to use the asm version */
-
- int bars=0;
-
- #define NB_KEYS 32768
-
- /* Number of pixels per line on which the correlation is achieved.
- must be a multiple of 8 */
- #define CX_COUNT 24
-
- /* Number of couples of lines on which the correlation is
- achieved. You must modify it in the asm source too */
- #define NB_COUPLES 16
-
- /* The correlation use only the lines after LINE_MIN */
- /*#define LINE_MIN 96*/
- #define LINE_MIN 96
-
- /* The correlation use only the lines before LINE_MAX */
- #define LINE_MAX (286-96)
-
- unsigned short key_lines[NB_KEYS][NB_COUPLES];
- unsigned int couple_index[6000];
- int couple_index_nb;
- unsigned short correl_lines[6000];
-
- static unsigned char rgb_to_y[32768];
-
- /* init variables */
- int nb_couples;
-
- int *couple_next;
- int *couple_first;
- int *couple_score;
- int *couple_nb;
-
- void decode_frame(unsigned char *dest,int dest_xsize,
- unsigned char **lines,int xsize,int ysize,
- int gray_scale,int full_pal, int g32bit)
- {
- int y,x,format,xsize1;
- unsigned short perm[287];
- register short *p2;
- register unsigned char *p1;
- unsigned char *pc;
- unsigned int t1, t2;
- int diff;
- int decode;
-
- if (gray_scale) xsize1=xsize; else xsize1=2*xsize;
-
-
- /* find the permutation */
- format = 0; /* 15 bit */
- if (g32bit) format = 1;
-
- decode = decode_nagra(perm,(void **)lines,xsize,format);
-
- /* do the permutation */
- if (!full_pal)
- {
- if (format == 0)
- {
- p2 = (short *) dest+bars*dest_xsize;;
- for (y = bars; y < YSIZE-bars; y++)
- {
- p1 = lines[y];
- if (decode==0) p1 = lines[perm[y]];
- for (x = 0; x < (384/2); x++)
- {
- ((unsigned int *) p2)[0] = ((unsigned int *) p1)[0];
- p2 += 2;
- p1 += 4;
- }
- p2 += dest_xsize - 384;
- }
- } else { /* format: 32 bit digitized */
- p2 = (short *) dest+bars*dest_xsize;;
- for (y = bars; y < YSIZE-bars; y++)
- {
- p1 = lines[y];
- if (decode==0) p1 = lines[perm[y]];
-
- for (x = 0; x < (384/2); x++)
- {
- ((unsigned int *) p2)[0] = ((p1[1]<<(7+16))&0x7c000000)
- | ((p1[2]<<(2+16))&0x03e00000)
- | ((p1[3]<<13)&0x001f0000)
- | ((p1[5]<<7)&0x7c00)
- | ((p1[6]<<2)&0x03e0)
- | ((p1[3]>>3)&0x001f);
- p2 += 2;
- p1 += 8;
- }
- p2 += dest_xsize - 384;
- }
- }
- } else {
- p2 = (short *) dest+bars*dest_xsize;
- for (y = bars; y < YSIZE-bars; y++)
- {
- p1 = lines[y];
- if (decode==0) p1 = lines[perm[y]];
- for (x = 0; x < (384/2); x++)
- {
- ((unsigned int *) p2)[0] = ((unsigned short *) p1)[0] | (((unsigned short *) p1)[0]<<16);
- ((unsigned int *) (p2+dest_xsize))[0] = ((unsigned short *) p1)[0] | (((unsigned short *) p1)[0]<<16);
- ((unsigned int *) p2)[1] = ((unsigned short *) p1)[1] | (((unsigned short *) p1)[1]<<16);
- ((unsigned int *) (p2+dest_xsize))[1] = ((unsigned short *) p1)[1] | (((unsigned short *) p1)[1]<<16);
- p2 += 4;
- p1 += 4;
- }
- p2 += dest_xsize - 384*2;
- p2 += dest_xsize;
- }
- }
- }
-
- /* compute the permutation generated by the 15 bit key 'key' */
- static void gen_perm(unsigned short *perm,int key)
- {
- int key_start,key_inc,key_index,i,b;
- int buffer[32];
-
- key_start=key >> 7;
- key_inc=(key & 0x7f)*2+1;
-
- for(i=0;i<32;i++) buffer[i]=i;
-
- key_index=key_start;
- for(i=0;i<255;i++) {
- b=table_keys[key_index];
- perm[i]=buffer[b];
- buffer[b]=i+32;
-
- key_index=(key_index+key_inc) & 0xff;
- }
-
- for(i=0;i<32;i++) {
- perm[255+i]=buffer[i];
- }
- }
-
-
- void add_couple(int c)
- {
- int p,key,q,y1,y2,nb;
-
- y1=c / YSIZE;
- y2=c % YSIZE;
- couple_index[couple_index_nb]=(y1 << 9) | y2;
-
- p=couple_first[c];
- while (p!=-1) {
- key=p / nb_couples;
- nb=couple_nb[key]++;
- q=couple_next[p];
- if (nb < NB_COUPLES) {
- key_lines[key][nb]=couple_index_nb*2;
- }
- p=q;
- }
- couple_index_nb++;
- }
-
- int score_couple(int c)
- {
- int p,key,score;
-
- score=0;
- p=couple_first[c];
- while (p!=-1) {
- key=p / nb_couples;
- if (couple_nb[key] < NB_COUPLES) score++;
- p=couple_next[p];
- }
- return score;
- }
-
-
- static void init_decode_tables(void)
- {
- int key,i,j,last_y,y,p,q,score;
- unsigned short perm[YSIZE];
- int nb_tot,score_max;
- int line_min=LINE_MIN,line_max=LINE_MAX;
-
- nb_couples=line_max-line_min;
-
- couple_next=malloc(sizeof(int)*nb_couples*NB_KEYS);
- couple_first=malloc(YSIZE*YSIZE*sizeof(int));
- couple_score=malloc(YSIZE*YSIZE*sizeof(int));
- couple_nb=malloc(NB_KEYS*sizeof(int));
-
- for(i=0;i<YSIZE*YSIZE;i++) couple_first[i]=-1;
- for(i=0;i<YSIZE*YSIZE;i++) couple_score[i]=0;
-
- for(key=0;key<NB_KEYS;key++) {
- gen_perm(perm,key);
-
- last_y=perm[line_min];
- for(i=line_min+1;i<=line_max;i++) {
- y=perm[i];
- if (y < last_y) j=y*YSIZE+last_y; else j=last_y*YSIZE+y;
- last_y=y;
-
- q=(key*nb_couples)+i-(line_min+1);
- p=couple_first[j];
- couple_next[q]=p;
- couple_first[j]=q;
- couple_score[j]++;
- }
-
- }
-
- for(i=0;i<NB_KEYS;i++) couple_nb[i]=0;
-
- nb_tot=0;
- couple_index_nb=0;
- do {
- score_max=0;
- j=0;
- for(i=0;i<YSIZE*YSIZE;i++) {
- if (couple_score[i] > score_max) {
- score_max=couple_score[i];
- j=i;
- }
- }
- score=score_couple(j);
- if (score > 0) {
- nb_tot+=score;
- add_couple(j);
- }
- couple_score[j]=0;
- } while (nb_tot < (NB_KEYS*NB_COUPLES)) ;
-
- free(couple_nb);
- free(couple_score);
- free(couple_first);
- free(couple_next);
-
- }
-
- void init_decode_nagra(void)
- {
- int i;
-
- /* memcpy(table_keys,table,256); */
-
- init_decode_tables();
-
- /* we precompute the table for rgb_to_y conversion */
- for(i=0;i<32768;i++) {
- int r,g,b,y;
-
- r=(i >> 10) << 3;
- g=((i >> 5) & 0x1f) << 3;
- b=(i & 0x1f) << 3;
- y=(int)(77.0 * r + 150.0 * g + 29.0 * b + 128.0) >> 8;
- if (y>255) y=255;
- rgb_to_y[i]=y;
- }
- }
-
- /* asm version for NB_COUPLES == 12 or 10 (see try_perm.S for the x86 asm version) */
- unsigned short *try_perm1(void);
-
- /*
- * C version of try_perm
- */
- unsigned short *try_perm(void)
- {
- int corr_min;
- unsigned short *key_end,*key_min;
- register unsigned short *key_ptr;
- register int corr;
-
- corr_min=0x7fffffff;
- key_min=NULL;
- key_ptr=(unsigned short *)key_lines;
- key_end=key_ptr+NB_KEYS*NB_COUPLES;
-
- /* fast correlation on a few lines */
- do {
-
- corr=0;
- #if NB_COUPLES == 12
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[10]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[11]);
- #elif NB_COUPLES == 10
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
- #elif NB_COUPLES == 8
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
- #elif NB_COUPLES == 16
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[10]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[11]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[12]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[13]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[14]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[15]);
- #elif NB_COUPLES == 24
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[0]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[1]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[2]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[3]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[4]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[5]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[6]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[7]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[8]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[9]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[10]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[11]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[12]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[13]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[14]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[15]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[16]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[17]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[18]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[19]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[20]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[21]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[22]);
- corr+=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[23]);
- #else
- {
- int j,c;
- for(j=0;j<NB_COUPLES;j++) {
- c=*(unsigned short *)((unsigned char *)correl_lines + key_ptr[j]);
- corr+=c;
- }
- }
- #endif
-
- key_ptr+=NB_COUPLES;
-
- /* test correlation */
- if (corr < corr_min) {
- corr_min=corr;
- key_min=key_ptr;
- }
- } while (key_ptr < key_end);
-
- return (key_min - NB_COUPLES);
- }
-
- /* the following variables are used to look at the 25 frame key
- repetition. It is for information purpose only since it is not used
- in the current code. */
-
-
- int decode_nagra(unsigned short *perm,
- void **lines,int xsize,int format)
- {
- int i,j,k;
- unsigned char pts_buffer[YSIZE][CX_COUNT],*p;
- int corr,key;
- unsigned short *correl_lines_ptr,*key_ptr;
- int cx_inc,cx_start;
- #ifdef PROFILE
- int ti=clock();
- #endif
-
- cx_inc=xsize/CX_COUNT;
- cx_start=cx_inc/2;
- p=&pts_buffer[0][0];
-
- /* preload of the pixels used for the correlation */
-
- if (format == 0)
- {
- /* 15 bits format */
- for(i=0;i<YSIZE;i++) {
- unsigned short *q;
- q=((unsigned short **)lines)[i]+cx_start;
- for(j=0;j<CX_COUNT;j+=4) {
- p[0]=rgb_to_y[q[0]];
- q+=cx_inc;
- p[1]=rgb_to_y[q[0]];
- q+=cx_inc;
- p[2]=rgb_to_y[q[0]];
- q+=cx_inc;
- p[3]=rgb_to_y[q[0]];
- q+=cx_inc;
- p+=4;
- }
- }
- } else {
- /* 32 bits format */
- for(i=0;i<YSIZE;i++) {
- unsigned short *q;
- q=((unsigned short **)lines)[i]+cx_start;
- for(j=0;j<CX_COUNT;j+=4) {
- p[0]= (int)( 77.0*((unsigned char *)q)[1] /* r */
- +150.0*((unsigned char *)q)[2] /* g */
- + 29.0*((unsigned char *)q)[3] /* b */
- +128.0)>>8;
- q+=cx_inc*2;
- p[1]= (int)( 77.0*((unsigned char *)q)[1] /* r */
- +150.0*((unsigned char *)q)[2] /* g */
- + 29.0*((unsigned char *)q)[3] /* b */
- +128.0)>>8;
- q+=cx_inc*2;
- p[2]= (int)( 77.0*((unsigned char *)q)[1] /* r */
- +150.0*((unsigned char *)q)[2] /* g */
- + 29.0*((unsigned char *)q)[3] /* b */
- +128.0)>>8;
- q+=cx_inc*2;
- p[3]= (int)( 77.0*((unsigned char *)q)[1] /* r */
- +150.0*((unsigned char *)q)[2] /* g */
- + 29.0*((unsigned char *)q)[3] /* b */
- +128.0)>>8;
- q+=cx_inc*2;
- p+=4;
- }
- }
- }
-
- /* Precompute the correlation between the lines. It could be
- optmized further. */
- correl_lines_ptr=correl_lines;
- for(i=0;i<couple_index_nb;i++) {
- int v,y1,y2;
- unsigned char *p1,*p2;
- v=couple_index[i];
- y1=v >> 9;
- y2=v & 0x1ff;
-
- p1=&pts_buffer[y1][0];
- p2=&pts_buffer[y2][0];
-
- corr=0;
- for(k=0;k<CX_COUNT;k+=8) {
- corr+=abs((int)p1[0]-(int)p2[0]);
- corr+=abs((int)p1[1]-(int)p2[1]);
- corr+=abs((int)p1[2]-(int)p2[2]);
- corr+=abs((int)p1[3]-(int)p2[3]);
- corr+=abs((int)p1[4]-(int)p2[4]);
- corr+=abs((int)p1[5]-(int)p2[5]);
- corr+=abs((int)p1[6]-(int)p2[6]);
- corr+=abs((int)p1[7]-(int)p2[7]);
- p1+=8;
- p2+=8;
- }
- *correl_lines_ptr++=corr;
- }
-
- key_ptr=try_perm();
- key=(key_ptr - (unsigned short *)key_lines) / NB_COUPLES;
-
- gen_perm(perm,key);
-
- if (key_buf[key_buf_ptr] == key) {
- key_locked='*';
- } else {
- key_locked=' ';
- }
- key_buf[key_buf_ptr++]=key;
- if (key_buf_ptr == KEY_BUF_SIZE) key_buf_ptr=0;
-
- #ifdef PROFILE
- ti=clock() - ti;
- fprintf(stderr,"key: %04X time=%0.3fs\n",key,
- (double) ti / CLOCKS_PER_SEC);
- #endif
-
- return 0;
- }
-